USE Flags
目录
USE
flag 用于控制可选的依赖和用户可能会希望选择的设置。例如, app-editors/vim
可以可选的构建支持 ruby 解释器,并且它需要安装 dev-lang/ruby
来达成此目的 —— 我们使用 ruby USE
flag 来提供这个选项。在另一方面, app-test/glark
无论什么都要求 ruby
,所以在这里没有使用 USE
flag。
USE
flag 的任何组合都不应导致软件包构建失败,因为用户可以设置任何组合的 flag。
软件包不应基于编译时可用的内容进行配置和链接 —— 任何自动检测都必须被覆盖。这通常指依赖项"automagic"。这很不好,因为包管理器无法间的到该依赖,并且很容易破坏依赖和一些其他的问题。
automagic 依赖最好通过准备构建系统 patch 来修复,其 patch 添加适当的选项来控制有疑问的依赖,并且提交该 patch 到上游让所有用户收益。为避免在下游携带附加的补丁,通常可以使用特殊的构建系统选项来解决(例如在 autotools 中缓存变量)或无条件的依赖相关软件包来解决 automagic 依赖(即强制检查总是成功)。
Note: USE flag 的状态保存在 VDB 中,并且它们在
pkg_prerm
和pkg_postrm
中的值从这里获取。这意味着在 merge 和 unmerge 之间设置或取消设置 USE flag 是无效的。
When not to use USE flags?
尽管通常认为 USE
flag 对用户有利,但也有一些避免使用它们的有效用例。当写 ebuild 时的,考虑是否为一个特定功能添加 flag,或探索以下描述的替代方案之一。
当软件包未链接时, USE
flag 的使用不应该控制运行时依赖。这样做会未软件包创建额外的配置,并重新编译磁盘上没有更改的底层文件。这应该避免这种情况,改为如果有需要则通过安装后的消息传达给用户。
USE
flag 不得用于控制小型、非侵入式、不会引入其他构建时依赖或导致构建时间显著增加的文件。例如此类文件包括 bash 补全文件,init.d 脚本,logrotate 配置文件,systemd 服务文件。基本原理与上述相同。这些文件必须无条件的安装。
对于具有多个条件程序或模块的包,可以进行类似的处理。每当这会导致大量的 USE
flag,迫使用户花费大量的时间选择兼容的 flag,并可能在不完整的选择后重新构建,考虑减少将 flag 用于那些具有外部依赖和/或构建时间较长的程序或模块。剩余的部分应该改为无条件构建,或由像 minimal
的 flag 控制。
你不应该引入仅用于操作 CFLAGS
、 FEATRUES
等类似由用户直接配置的变量的 USE flag。反而,软件包应避免操作它们,并让用户直接设置它们。常见的错误包括:
- 使用
debug
USE flag 来强制-O0 -g
并禁用 stripping。debug
flag 的正确目的应该是控制附加的调试代码路径。用户应该负责使用正确的 flags 和特性来保留调试信息。 - 引入
lto
flag 并强制-flto
。这是用户应该直接在 flag 变量设置的。 - 使用
CPU_FLAGS_*
来控制-m*
选项。这些 flag 旨在显式控制要求特定 CPU 扩展的代码路径,例如 separate assembly。编译器生成的程序集应尊重用户的-march
选择。
在某些极端情况下,这些规则可能不适用。例如,一些上游要求用户使用特定的 CFLAGS
并且拒绝使用其他值构建的错误报告。在这种情况,默认情况下会 strip flag 并提供 custom-cflags
flag,以允许用户强制使用其首选 flag。
noblah
USE Flags
避免 noblah
风格的 use
flag。它们会破坏 use.mask
并且对架构开发者造成各种复杂问题。原因如下:
考虑一个名为'vplayer'的假想包,其功能为播放视频。该软件包通过 USE
flag 对各种声音和视频输出方法、各种视频解码等提供可选支持。
vplayer 的可选功能之一是提供对'fakemdia'的解码支持,不幸的是它仅以狡猾的 x86 二进制形式提供。我们通过执行嗯以下操作来解决此问题:
RDEPEND="x86? ( fakemdia? ( >=media-libs/fakemdia-1.1 ) )"
除了这种方法非常肮脏 —— 当 AMD64 二进制文件也这样做会发生什么?还有,在其他架构的用户会在 emerge -pv
输出中看到列出的 fakemdia,即使它实际上不可用。
类似的,假如 vplayer 将支持通过 ALSA 解码器输出作为一个选项。然而 ALSA 在 SPARC 或 Alpha 上不可用(或在编写此示例时)。所以我们可以这样做:
DEPEND="!sparc? ( !alpha? ( alsa? ( media-libs/alsa-lib ) ) )"
同样,这很混乱,并且 ALSA 同样会出现在 emerge -p
的输出中。而且,一旦 ALSA 开始在 SPARC 上工作时,每一个这么做的 ebuild 都必须手动编辑。
解决办法是 use.mask
,该文件记录在Profile use.make文件中。每个 profile 都可以有一个 use.mask
文件,该文件用于强制禁用给定架构(或子架构,或 subprofile)上的特定 USE flag。所以,如果 fakemdia
USE flag 在每一个非 x86 pofile 的 use.mask 中,以下内容完全合法并且不会破坏任何内容:
RDEPEND="fakemedia? ( >=media-libs/fakemedia-1-1 )"
非 x86 的用户在执行 emerge -pv vplayer
时会看到以下内容:
[ebuild R ] media-video/vplayer-1.2 alsa -blah (-fakemedia) xyz
要向 use.mask
添加一个 flag,请询问相关的架构团队。
IUSE defaults
在 IUSE
中 use flag 的名称前添加 +
或 -
以默认将其打开或关闭。
Important:在
IUSE
中添加-
到 flag 之前时非常没有用的,因为它既不会覆盖用户的配置(make.conf
),也不会覆盖 profile 默认(make.defualts=和=package.use
)。有关 Portage 中 USE 顺序的详细信息,请参见 amke.conf(5)。
Local and Global USE Flags
USE flag 可分为本地或全局。一个全局 USE flag 必须满足几个标准:
- 它被许多不同的软件包使用,至少 5 个似乎满足以上条件。
- 它具有一般的非特定用途。
第二点非常重要。如果 USE flag 对 pkg-one
于对 pkg-two
的影响大不相同,那么该表示不是成为全局 flag 的合适候选者。尤其要注意,如果曾经引入 client
和 server
USE flag,则由于这个原因它们不能成为全局 USE flag。
在引入一个新的全局 USE flag 之前, 它必须在 gentoo-dev 邮件列表中进行讨论。
USE Flag Descriptions
必须在 profile/
目录的 use.desc
或软件包目录的 metadata.xml
中描述所有 USE flag。见 man portage
或这些文件中的注释以获取格式说明。 记得保持这些文件的排序。 use.local.desc
文件自动从软件包的 metadata.xml
生成的,并且可以由解析树的工具使用。因为 use.local.desc
是自动生成的,因此绝对不能在树中进行手动编辑。更多信息见GLEP 56。
USE_EXPAND
flag 是一个例外,其必须记录在 profile/desc/
目录中。每个 USE_EXPAND
变量需要一个文件,该文件必须包含该变量可以采用的可能的值的说明。格式见这些文件中的注释,并且记住保持这些文件的排序。
Conflicting USE Flags
偶尔 ebuild 的 USE 会因为功能性产生冲突。检查它们并返回一个错误不是一个可行的方法。相反,你必须在冲突中选择一个青睐的 USE flag,并应警告用户使用了特定的 flag。
一个示例来自 mail-mta/mstmp
ebuild。软件包可以使用代 GnuTLS 的 SSL,代 OpenSSL 的 SSL 或者完全不使用 SSL。因为 GnuTLS 比 OpenSSL 具有更多功能,因此受到青睐:
src_compile() { local myconf if use ssl && use gnutls ; then myconf="${myconf} --enable-ssl --with-ssl=gnutls" elif use ssl && ! use gnutls ; then myconf="${myconf} --enable-ssl --with-ssl=openssl" else myconf="${myconf} --disable-ssl" fi econf \ # Other stuff ${myconf} emake }
在某些特殊情况下,上述策略会破坏反向 USE 依赖。为了避免如此,ebuild 可以使用 REQUIRED_USE
指定允许的 USE flag 组合。关于其语法的描述请见REQUIRED_USE章节。
例如,如果一个软件包 dev-libs/foo
可以使用 USE="a"
或 USE="b"
之一构建,但不是同时使用,那么首选其中一个 flag 将破坏依赖于 dev-libs/foo[a]
或 dev-libs/foo[b]
的软件包。因此在这种情况中,ebuild 应该指定 REQUIRED_USE="a ? ( !b )"
。
NOTE: 为了避免迫使用户过多的 micro-manage falg,应谨慎的使用
REQUIRED_USE
。只要有可能进行满足用户需求的构建,就应遵循常规策略。
USE_EXPAND and ARCH USE Flags
VIDEO_CARDS
、 INPUT_DEVICES
和 L10N
变量会自动扩展为 USE flag。这些称为 USE_EXPAND
变量。例如,如果用户在 make.conf
中有 L10N="en fr"
,那么 USE="l10n_en l10n_fr"
会自动被 portage 设置。会自动被 portage 设置。会自动被 portage 设置。会自动被 portage 设置。
自 Prtage 2.0.51.20 其, USE_EXPAND
列表被设置在 profile/bas/make.defaults
中。未经过 gentoo-dev 列表的讨论,不能对其进行修改,并且在任何 subprofile 中也不能对其修改。
当前架构(例如, x86
、 sparc
、 ppc-macos
)会被自动设置为 USE flag。有关有效的有关架构关键词的完整列表,请见 profile/arch.list
,GLEP 22对其格式进行了说明。
Warning:架构变量与
ACCEPT_KEYWORDS
有某种联系是一个常见的误解。它们没有联系。例如,在sparc
上接受x86
关键字,并不会设置USE\"x86"
。类似的,也没有~arch
USE flag,所以不要尝试if use ~x86
。